package com.hoshino.momochi.aspect;

import com.google.common.collect.ImmutableList;
import com.hoshino.momochi.annotation.MaintainToken;
import com.hoshino.momochi.service.RedisService;
import com.hoshino.momochi.util.CodeEnum;
import com.hoshino.momochi.util.LuaScript;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Objects;


/**
 * check or maintain token
 *
 * @author TAKANASHI_HOSHINO
 */
@Aspect
@Component
@Slf4j
public class MaintainTokenAspect {

    @Autowired
    private RedisService redisService;

    private final RedisTemplate<String, Serializable> limitRedisTemplate;

    private final String USER_ID = CodeEnum.USERID.getMessage();
    private final String TOKEN = CodeEnum.TOKEN.getMessage();

    @Autowired
    public MaintainTokenAspect(RedisTemplate<String, Serializable> limitRedisTemplate) {
        this.limitRedisTemplate = limitRedisTemplate;
    }

    //login token操作
    @Pointcut("execution(* com.hoshino.momochi.controller.UserController.loginUser(..)) || execution(* com.hoshino.momochi.controller.LoginController.login(..)) || execution(* com.hoshino.momochi.controller.TestController.TestSetToken(..))")
    public void pointcutToSetToken() {
        // 在登录 处 创建 token 保存 于 redis 并 返回 至 前端
    }

    /**
     * @param joinPoint 在 指定 方法之前 判断 Token
     *                  并在判断之后 延长 TOKEN 存在时间
     *                  可能不存在 这个 TOKEN 则需要 登录
     *                  or
     *                  存在 该 TOKEN 则 正常登录
     */
//    @Before("pointcut()")
//    public void geTokenToCheck(JoinPoint joinPoint) {}
    @After("pointcutToSetToken()")
    public void setTokenAndReturn(JoinPoint joinPoint) {
        // 获取请求
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        // 获取注解参数
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        MaintainToken annotation = method.getAnnotation(MaintainToken.class);
        int latetime = annotation.latetime();

        // 获取 token
        String token = (String) request.getAttribute(TOKEN);
        // 获取 id
        Long id = (Long) request.getAttribute(USER_ID);

        if (token != null && id != null) {
            // run
//            Number count = redisService.MaintainToken(token, id, latetime);
            redisService.MapUserIdToToken(id, token, latetime);
            log.info("method:{} redis set expire成功", method.getName());
        }
        log.info("当前method:{}, token:{}, id:{}", method.getName(), token, id);
    }


}
